use crate::model::{BalatroModel, CARDH, CARDW};
use log::info;
use tge::{
    context::Context,
    event::{event_check, event_register},
    game::{Model, Render},
    render::sprite::{Sprite, Sprites},
    render::style::Style,
    render::terminal::Term,
};

pub struct BalatroRender {
    pub term: Term,
    pub sprites: Sprites,
    pub cards: Vec<Sprite>,
}

impl BalatroRender {
    pub fn new() -> Self {
        //把54张牌img存储在bs中,bs[tile_num - 1]可访问到对应牌图形
        let mut bs: Vec<Sprite> = vec![];
        for i in 0..=54usize {
            let mut ts = Sprite::new(0, 0, CARDW as u16, CARDH as u16);
            let cn = if i == 0 {
                format!("assets/poker/back.txt")
            } else {
                format!("assets/poker/{}.txt", i)
            };
            info!("load...{} {}", i, cn);
            ts.load_esc(&cn, 0, 0);
            bs.push(ts);
        }

        let t = Term::new();
        let mut s = Sprites::new("main");

        let mut gb = Sprite::new(0, 0, 80, 25);
        gb.load_esc("assets/redblack/back.txt", 0, 0);
        s.add_by_tag(gb, "back");

        //red 5张牌, black 5张牌
        for i in 0..10 {
            s.add_by_tag(
                Sprite::new(0, 0, CARDW as u16, CARDH as u16),
                &format!("t{}", i),
            );
        }

        let adj = 1u16;
        let msgred = Sprite::new(0 + adj, 13, 40, 1);
        s.add_by_tag(msgred, "msgred");
        let msgblack = Sprite::new(40 + adj, 13, 40, 1);
        s.add_by_tag(msgblack, "msgblack");

        event_register("Balatro.RedrawTile", "draw_tile");

        Self {
            term: t,
            sprites: s,
            cards: bs,
        }
    }

    pub fn draw_tile<G: Model>(&mut self, _context: &mut Context, model: &mut G) {
        let d = model.as_any().downcast_mut::<BalatroModel>().unwrap();
        let ts = [&d.texas_cards_red, &d.texas_cards_black];
        let msg = ["msgred", "msgblack"];
        for n in 0..2usize {
            for i in 0..5 {
                let l = self.sprites.get_by_tag(&format!("t{}", i + n * 5));
                let bi = ts[n].best[i].to_u8() as usize;
                l.copy_content(&self.cards[bi]);
                let x = (i * CARDW) as u16 + 1u16 + n as u16 * 40u16;
                l.set_pos(x, 7);
            }
            let m = self.sprites.get_by_tag(msg[n]);
            m.content
                .set_str(0, 0, format!("{:?}", ts[n].texas), Style::default());
        }
    }
}

impl Render for BalatroRender {
    fn init(&mut self, context: &mut Context) {
        context.adapter.init(85, 24, 1.0, 1.0, "balatro".to_string());
        self.term.init(context);
    }

    fn handle_event<G: Model>(&mut self, context: &mut Context, data: &mut G, _dt: f32) {
        if event_check("Balatro.RedrawTile", "draw_tile") {
            self.draw_tile(context, data);
        }
    }

    fn handle_timer<G: Model>(&mut self, _context: &mut Context, _model: &mut G, _dt: f32) {}

    fn draw<G: Model>(&mut self, ctx: &mut Context, _data: &mut G, _dt: f32) {
        self.term
            .draw(ctx, |f| {
                f.render_widget(self.sprites.get_by_tag("back"));
                for i in 0..10 {
                    let ss = self.sprites.get_by_tag(&format!("t{}", i));
                    f.render_widget(ss);
                }
                f.render_widget(self.sprites.get_by_tag("msgred"));
                f.render_widget(self.sprites.get_by_tag("msgblack"));
            })
            .unwrap();
    }
}
